home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume0 / awm / part10 < prev    next >
Encoding:
Internet Message Format  |  1988-08-10  |  29.2 KB

  1. Path: uunet!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v00i011:  Ardent Window Manager(X11), Part10/13
  5. Message-ID: <1634@wyse.wyse.com>
  6. Date: 10 Aug 88 22:00:12 GMT
  7. Sender: news@wyse.wyse.com
  8. Lines: 1306
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: unido!pcsbst!jkh (Jordan Hubbard)
  12. Posting-number: Volume 0, Issue 11
  13. Archive-name: awm/part10
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 10 (of 13)."
  22. # Contents:  awm/gram.y
  23. # Wrapped by mikew@wyse on Mon Aug  8 12:01:47 1988
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f awm/gram.y -a "${1}" != "-c" ; then 
  26.   echo shar: Will not over-write existing file \"awm/gram.y\"
  27. else
  28. echo shar: Extracting \"awm/gram.y\" \(26836 characters\)
  29. sed "s/^X//" >awm/gram.y <<'END_OF_awm/gram.y'
  30. X/*
  31. X *
  32. X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  33. X *
  34. X * Copyright 1987 by Jordan Hubbard.
  35. X *
  36. X *
  37. X *                         All Rights Reserved
  38. X *
  39. X * Permission to use, copy, modify, and distribute this software and its
  40. X * documentation for any purpose and without fee is hereby granted,
  41. X * provided that the above copyright notice appear in all copies and that
  42. X * both that copyright notice and this permission notice appear in
  43. X * supporting documentation, and that the name of Ardent Computer
  44. X * Corporation or Jordan Hubbard not be used in advertising or publicity
  45. X * pertaining to distribution of the software without specific, written
  46. X * prior permission.
  47. X *
  48. X */
  49. X
  50. X/*
  51. X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  52. X *
  53. X *                         All Rights Reserved
  54. X *
  55. X * Permission to use, copy, modify, and distribute this software and its
  56. X * documentation for any purpose and without fee is hereby granted,
  57. X * provided that the above copyright notice appear in all copies and that
  58. X * both that copyright notice and this permission notice appear in
  59. X * supporting documentation, and that the name of Digital Equipment
  60. X * Corporation not be used in advertising or publicity pertaining to
  61. X * distribution of the software without specific, written prior permission.
  62. X *
  63. X *
  64. X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  65. X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  66. X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  67. X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  68. X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  69. X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  70. X * SOFTWARE.
  71. X */
  72. X
  73. X
  74. X/*
  75. X * MODIFICATION HISTORY
  76. X *
  77. X * 000 -- M. Gancarz, DEC Ultrix Engineering Group
  78. X * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group
  79. X *  Western Software Lab. Convert to X11.
  80. X * 002 -- Jordan Hubbard, U.C. Berkeley. New keywords. Menu
  81. X * changes, gadget boxes, title bars, the kitchen sink.
  82. X */
  83. X
  84. X%{
  85. X
  86. X#ident   "%W% %G%"
  87. X
  88. X
  89. X
  90. X#ifndef lint
  91. Xstatic char *rcsid_gram_y = "$Header: gram.y,v 1.4 88/07/24 01:01:04 jkh Exp $";
  92. X#endif    lint
  93. X
  94. X#include "X11/Xlib.h"
  95. X#include "X11/Xutil.h"
  96. X#include "awm.h"
  97. X#include <signal.h>
  98. X
  99. X/*
  100. X * Values returned by complex expression parser.
  101. X */
  102. X#define C_STRING    1    /* IsString. */
  103. X#define C_MENU        2    /* IsMenu. */
  104. X#define C_MAP        3    /* IsMap. */
  105. X#define C_MENUMAP    4    /* IsMenuMap */
  106. X#define C_PIXMAP    5    /* IsPixmap */
  107. X#define C_ACTION    6    /* IsAction */
  108. X     static int ki;            /* Keyword index. */
  109. X     static int gadgnum;        /* # of gadget we're initing */
  110. X     static int g_offset;        /* The gadget offset specified */
  111. X     static int g_gravity;        /* The gadget gravity specified */
  112. X     static char *g_forecolor;        /* gadget foreground color */
  113. X     static char *g_backcolor;        /* gadget background color */
  114. X     static XFontStruct *g_font;    /* gadget font */
  115. X     static int bkmask;            /* Button/key mask. */
  116. X     static int cmask;            /* Context mask. */
  117. X     static char msg[BUFSIZ];        /* Error message buffer. */
  118. X     static char *menu_name;        /* Menu name. */
  119. X     static char *menu_pixmap;        /* Name of pixmap for menu label */
  120. X     static MenuInfo *menu_info;    /* Menu info. */
  121. X     static ActionLine *ml_ptr;        /* Temporary menu line pointer. */
  122. X     static ActionLine *action;        /* Temporary action pointer */
  123. X     MenuLink *menu_link;        /* Temporary menu link pointer. */
  124. X     GadgetDecl **Gadgets;        /* Pointer to gadget info structs */
  125. X     char *calloc();
  126. X
  127. X     %}
  128. X
  129. X%union {
  130. X     char *sval;
  131. X     int ival;
  132. X     short shval;
  133. X     struct _actionline *alval;
  134. X     struct _menuinfo *mival;
  135. X     char **cval;
  136. X}
  137. X
  138. X%token NL
  139. X     %token <sval> STRING
  140. X     %token <ival> COMMENT
  141. X     %type <sval> pixmap_file
  142. X     %type <ival> gadget_subscript
  143. X     %type <ival> keyword
  144. X     %type <ival> compexpr
  145. X     %type <ival> keyexpr
  146. X     %type <ival> kmask
  147. X     %type <ival> contexpr
  148. X     %type <ival> contmask
  149. X     %type <ival> buttmodexpr
  150. X     %type <ival> buttmodifier
  151. X     %type <ival> buttexpr
  152. X     %type <sval> menuname
  153. X     %type <sval> strings
  154. X     %type <alval> textaction
  155. X     %type <alval> menuexpr
  156. X     %type <alval> menulist
  157. X     %type <alval> menuline
  158. X     %type <alval> menuaction
  159. X
  160. X     %%    /* beginning of rules section */
  161. X     
  162. X input:    |    input command
  163. X     |    input error command { yyerrok; }
  164. X;
  165. X
  166. X command:    boolvar term
  167. X     |    expr term
  168. X     |    COMMENT    { Lineno++; }
  169. X     |    term
  170. X     ;
  171. X
  172. X term:        NL    { Lineno++; }
  173. X|    ';'
  174. X     ;
  175. X
  176. X expr:        keyword '=' compexpr
  177. X{
  178. X     switch (KeywordTable[$1].type) {
  179. X     case IsQuitFunction:
  180. X     case IsFunction:
  181. X      if ($3 == C_MAP) {
  182. X           bindtofunc($1, bkmask, cmask, NULL);
  183. X      } else yyerror("illegal construct");
  184. X      break;
  185. X
  186. X     case IsDownFunction:
  187. X      if (bkmask & ButtonUp) {
  188. X           sprintf(msg,
  189. X               "cannot bind %s to button up",
  190. X               KeywordTable[$1].name);
  191. X           yyerror(msg);
  192. X      }
  193. X      if ($3 == C_MAP) {
  194. X           bindtofunc($1, bkmask, cmask, NULL);
  195. X      } else yyerror("illegal construct");
  196. X      break;
  197. X
  198. X     case IsMenuMap:
  199. X      if (bkmask & ButtonUp) {
  200. X           sprintf(msg,
  201. X               "cannot bind %s to button up",
  202. X               KeywordTable[$1].name);
  203. X           yyerror(msg);
  204. X      }
  205. X      if ($3 == C_MENUMAP) {
  206. X           bindtofunc
  207. X            ($1, bkmask, cmask, menu_name);
  208. X      } else yyerror("illegal construct");
  209. X      break;
  210. X
  211. X     case IsAction:
  212. X      if ($3 == C_ACTION) {
  213. X           /*
  214. X        * We pass a structure pointer here where a char pointer
  215. X        * is supposed to go. It was a hack, what can I say.
  216. X        */
  217. X           bindtofunc
  218. X            ($1, bkmask, cmask, (char *)action);
  219. X      } else yyerror("illegal construct");
  220. X      break;
  221. X
  222. X     case IsMenu:
  223. X      if ($3 == C_MENU) {
  224. X           /*
  225. X        * create a menu definition entry.
  226. X        */
  227. X           menu_info = stashmenuinfo(menu_name, ml_ptr, menu_pixmap);
  228. X           menu_link = stashmenulink(menu_info);
  229. X           Menus = appendmenulink(Menus, menu_link);
  230. X      } else yyerror("illegal menu construct");
  231. X      break;
  232. X
  233. X     case IsGadget:
  234. X      if (gadgnum < 0) {
  235. X           sprintf(msg, "Gadget number must be >= 0\n");
  236. X           yyerror(msg);
  237. X      }
  238. X      /* Bump NumGadgets if necessary */
  239. X      else if (gadgnum >= NumGadgets)
  240. X           NumGadgets = gadgnum + 1;
  241. X      if (NumGadgets > MAX_GADGETS) {
  242. X           sprintf(msg, "\"numgadgets\" (%d) is > MAX_GADGETS (%d)\n",
  243. X               NumGadgets, MAX_GADGETS);
  244. X           yyerror(msg);
  245. X      }
  246. X      else {
  247. X           if ($3 != C_STRING && $3 != C_PIXMAP)
  248. X            yyerror("Illegal gadget assignment");
  249. X           else
  250. X            stashGadget(gadgnum, yylval.sval, $3);
  251. X      }
  252. X      break;
  253. X
  254. X     default:
  255. X      yyerror("internal binding error");
  256. X      break;
  257. X     }
  258. X}
  259. X;
  260. X pixmap_file:    '(' STRING ')' {
  261. X      $$ = $2;
  262. X }
  263. X;
  264. X compexpr:    keyexpr ':' contexpr ':' buttexpr
  265. X{
  266. X     $$ = C_MAP;
  267. X     bkmask = $1 | $5;
  268. X     cmask = $3;
  269. X}
  270. X|    keyexpr ':' contexpr ':' buttexpr ':' menuname
  271. X{
  272. X     $$ = C_MENUMAP;
  273. X     bkmask = $1 | $5;
  274. X     cmask = $3;
  275. X     menu_name = $7;
  276. X}
  277. X|    keyexpr ':' contexpr ':' buttexpr ':' textaction
  278. X{
  279. X     $$ = C_ACTION;
  280. X     bkmask = $1 | $5;
  281. X     cmask = $3;
  282. X     action = $7;
  283. X}
  284. X|    STRING menuexpr
  285. X{
  286. X     $$ = C_MENU;
  287. X     menu_name = $1;
  288. X     menu_pixmap = 0;
  289. X     ml_ptr = $2;
  290. X}
  291. X|    pixmap_file STRING menuexpr
  292. X{
  293. X     $$ = C_MENU;
  294. X     menu_name = $2;
  295. X     menu_pixmap = $1;
  296. X     ml_ptr = $3;
  297. X}
  298. X|    STRING '^' gadgetspec
  299. X{ yylval.sval = $1; $$ = C_STRING; }
  300. X|    pixmap_file '^' gadgetspec
  301. X{ yylval.sval = $1; $$ = C_PIXMAP; }
  302. X|    STRING
  303. X{
  304. X     $$ = C_STRING;
  305. X     /* just in case it's a gadget, set defaults */
  306. X     g_forecolor = Foreground;
  307. X     g_backcolor = Background;
  308. X     g_gravity = NoGadgetGravity;
  309. X     g_offset = 0;
  310. X     g_font = 0;
  311. X}
  312. X|    pixmap_file
  313. X{
  314. X     $$ = C_PIXMAP;
  315. X     /* just in case it's a gadget, set defaults */
  316. X     g_forecolor = Foreground;
  317. X     g_backcolor = Background;
  318. X     g_gravity = NoGadgetGravity;
  319. X     g_offset = 0;
  320. X     g_font = 0;
  321. X}     
  322. X;
  323. X gadgetspec:     offset
  324. X|  offset '|' gravity
  325. X|  offset '|' gravity '|' forecolor
  326. X|  offset '|' gravity '|' forecolor '|' backcolor
  327. X|  offset '|' gravity '|' forecolor '|' backcolor '|' fontspec
  328. X;
  329. X offset: /* empty */
  330. X{ g_offset = 0; }
  331. X| STRING
  332. X{
  333. X    g_offset = y_atoi($1);
  334. X    g_gravity = NoGadgetGravity;
  335. X    g_forecolor = Foreground;
  336. X    g_backcolor = Background;
  337. X    g_font = (XFontStruct *)NULL;
  338. X}
  339. X;
  340. X gravity: /* empty */
  341. X{ g_gravity = NoGadgetGravity; }
  342. X| STRING
  343. X{
  344. X    g_gravity = gravitylookup($1);
  345. X    g_forecolor = Foreground;
  346. X    g_backcolor = Background;
  347. X    g_font = (XFontStruct *)NULL;
  348. X}
  349. X;
  350. X forecolor: /* empty */
  351. X{ g_forecolor = Foreground; }
  352. X| STRING
  353. X{
  354. X    g_forecolor = $1;
  355. X    g_backcolor = Background;
  356. X    g_font = (XFontStruct *)NULL;
  357. X}
  358. X;
  359. X backcolor: /* empty */
  360. X{ g_backcolor = Background; }
  361. X| STRING
  362. X{
  363. X    g_backcolor = $1;
  364. X    g_font = (XFontStruct *)NULL;
  365. X}
  366. X;
  367. X fontspec: /* empty */
  368. X{ g_font = 0; }
  369. X| STRING
  370. X{
  371. X     g_font = XLoadQueryFont(dpy, $1);
  372. X     if (!g_font) {
  373. X      sprintf(msg, "Can't open gadget font '%s'\n", $1);
  374. X      yywarn(msg);
  375. X     }
  376. X}
  377. X;
  378. X
  379. X boolvar:    STRING
  380. X{
  381. X     ki = keywordlookup(yylval.sval);
  382. X     switch (KeywordTable[ki].type) {
  383. X     case IsParser:
  384. X      (*KeywordTable[ki].fptr)();
  385. X      break;
  386. X     default:
  387. X      yyerror("keyword error");
  388. X     }
  389. X}
  390. X;
  391. X
  392. X keyword:    STRING    {
  393. X      $$ = keywordlookup(yylval.sval);
  394. X }
  395. X|    STRING gadget_subscript {
  396. X     $$ = keywordlookup("gadget");
  397. X     gadgnum = $2;
  398. X}
  399. X;
  400. X
  401. X gadget_subscript:    '[' STRING ']' {
  402. X      $$ = y_atoi(yylval.sval);
  403. X }
  404. X;
  405. X
  406. X keyexpr:    /* empty */
  407. X{ $$ = 0; }
  408. X|    kmask
  409. X{ $$ = $1; }
  410. X|    kmask '|' keyexpr
  411. X{ $$ = $1 | $3; }
  412. X;
  413. X
  414. X contexpr:    /* empty */
  415. X{ $$ = 0xffffffff; }
  416. X|    contmask
  417. X{ $$ = $1; }
  418. X|    contmask '|' contexpr
  419. X{ $$ = $1 | $3; }
  420. X;
  421. X
  422. X buttexpr:    buttmodexpr
  423. X{ $$ = CheckButtonState($1); }
  424. X;
  425. X
  426. X kmask:        STRING { $$ = keyexprlookup(yylval.sval); }
  427. X
  428. X contmask:    STRING
  429. X{ $$ = contexprlookup(yylval.sval); }
  430. X|    STRING gadget_subscript
  431. X{ 
  432. X     if ($2 < 0 || $2 >= NumGadgets) {
  433. X      sprintf(msg, "Bad subscript, gadget #%d must be >= 0 and < %d\n",
  434. X          $2, NumGadgets);
  435. X      yyerror(msg);
  436. X     }
  437. X     else {
  438. X      $$ = contexprlookup("gadget") | (1 << (BITS_USED + $2));
  439. X     }
  440. X}
  441. X;
  442. X buttmodexpr:     buttmodifier
  443. X{ $$ = $1; }
  444. X|    buttmodexpr buttmodifier
  445. X{ $$ = $1 | $2; }
  446. X;
  447. X
  448. X buttmodifier:    STRING
  449. X{ $$ = buttexprlookup(yylval.sval); }
  450. X;
  451. X
  452. X menuname:    STRING
  453. X{ $$ = $1; }
  454. X;
  455. X
  456. X menuexpr:    '{' menulist '}'
  457. X{ $$ = $2; }
  458. X;
  459. X
  460. X menulist:    menuline
  461. X{ $$ = $1; }
  462. X|    menulist menuline
  463. X{ $$ = appendmenuline($1, $2); }
  464. X|    menulist COMMENT
  465. X{
  466. X     Lineno++;
  467. X     $$ = $1;
  468. X}
  469. X|    COMMENT
  470. X{
  471. X     Lineno++;
  472. X     $$ = NULL;
  473. X}
  474. X|    term
  475. X{ $$ = NULL; }
  476. X|    menulist term
  477. X{ $$ = $1; }
  478. X|    error term
  479. X{
  480. X     $$ = NULL;
  481. X     yyerrok;
  482. X}
  483. X;
  484. X
  485. X menuline:    strings ':' menuaction term
  486. X{
  487. X     $3->name = $1;
  488. X     $3->pixmapname = (char *)0;
  489. X     $$ = $3;
  490. X}
  491. X|    '(' strings ')' ':' menuaction term
  492. X{
  493. X     $5->pixmapname = $2;
  494. X     $5->name = $2;
  495. X     $$ = $5;
  496. X}
  497. X;
  498. X
  499. X menuaction:    STRING
  500. X{
  501. X     ki = keywordlookup(yylval.sval);
  502. X     if ((ki != -1) &&
  503. X     (KeywordTable[ki].type != IsFunction) &&
  504. X     (KeywordTable[ki].type != IsImmFunction) &&
  505. X     (KeywordTable[ki].type != IsQuitFunction) &&
  506. X     (KeywordTable[ki].type != IsBoolean) &&
  507. X     (KeywordTable[ki].type != IsDownFunction)) {
  508. X      sprintf(msg,
  509. X          "menu action \"%s\" not a function or variable",
  510. X          KeywordTable[ki].name);
  511. X      yyerror(msg);
  512. X     }
  513. X     ml_ptr = AllocActionLine();
  514. X     if (KeywordTable[ki].type == IsQuitFunction ||
  515. X    KeywordTable[ki].type == IsImmFunction)
  516. X      ml_ptr->type = IsImmFunction;
  517. X     else if (KeywordTable[ki].type == IsBoolean) {
  518. X      ml_ptr->type = IsVar;
  519. X      ml_ptr->text = (char *)KeywordTable[ki].bptr;
  520. X     }
  521. X     else
  522. X      ml_ptr->type = IsUwmFunction;
  523. X     ml_ptr->func = KeywordTable[ki].fptr;
  524. X     $$ = ml_ptr;
  525. X}
  526. X|    STRING ':' menuname
  527. X{
  528. X     ki = keywordlookup($1);
  529. X     if (ki != -1 &&
  530. X     KeywordTable[ki].type != IsMenuMap) {
  531. X      sprintf(msg,
  532. X          "menu action \"%s\" not a menu function",
  533. X          KeywordTable[ki].name);
  534. X      yyerror(msg);
  535. X     }
  536. X     ml_ptr = AllocActionLine();
  537. X     ml_ptr->type = IsMenuFunction;
  538. X     ml_ptr->text = $3;
  539. X     $$ = ml_ptr;
  540. X}
  541. X|    textaction
  542. X{ $$ = $1; }
  543. X;
  544. X
  545. X textaction: '!' strings
  546. X{
  547. X     $$ = StashActionLine(IsShellCommand, $2);
  548. X}
  549. X|    '^' strings
  550. X{
  551. X     $$ = StashActionLine(IsTextNL, $2);
  552. X}
  553. X|    '|' strings
  554. X{
  555. X     $$ = StashActionLine(IsText, $2);
  556. X}
  557. X;
  558. X
  559. X strings:    STRING    { $$ = yylval.sval; }
  560. X|    strings STRING
  561. X{ $$ = strconcat($1, $2); }
  562. X;
  563. X
  564. X%%
  565. X
  566. X/*
  567. X * Look up color named by "string" and return pixel value.
  568. X */
  569. XPixel LookupColor(string, cmap, fail)
  570. Xchar *string;
  571. XColormap cmap;
  572. XBoolean *fail;
  573. X{
  574. X     XColor vis_ret, act_ret;
  575. X
  576. X     Entry("LookupColor")
  577. X
  578. X     if (!XAllocNamedColor(dpy, cmap, string, &vis_ret, &act_ret)) {
  579. X     sprintf(msg, "Can't allocate color '%s', using default\n", string);
  580. X     yywarn(msg);
  581. X     if (fail)
  582. X          *fail = TRUE;
  583. X     Leave((Pixel)0)
  584. X     }
  585. X     if (fail)
  586. X      *fail = FALSE;
  587. X     Leave(vis_ret.pixel)
  588. X}
  589. X
  590. X/*
  591. X * Like LookupColor, but provides its own fallback in case of failure
  592. X * (currently 0).
  593. X */
  594. XPixel GetPixel(string, cmap)
  595. Xchar *string;
  596. XColormap cmap;
  597. X{
  598. X     XColor vis_ret, act_ret;
  599. X
  600. X     Entry("GetPixel")
  601. X
  602. X     if (!string)
  603. X     Leave((Pixel)0)
  604. X     if (!XAllocNamedColor(dpy, cmap, string, &vis_ret, &act_ret))
  605. X     Leave((Pixel)0)
  606. X     Leave(vis_ret.pixel)
  607. X}
  608. X
  609. X/*
  610. X * Look up a string in the keyword table and return its index, else
  611. X * return -1.
  612. X */
  613. Xint keywordlookup(string)
  614. Xchar *string;
  615. X{
  616. X     int i;
  617. X     
  618. X     Entry("keywordlookup")
  619. X
  620. X     for (i = 0; KeywordTable[i].name; i++) {
  621. X      if (!strcmp(KeywordTable[i].name, string)) {
  622. X           free(string);
  623. X           Leave(i)
  624. X      }
  625. X     }
  626. X     sprintf(msg,"keyword error: \"%s\"", string);
  627. X     yyerror(msg);
  628. X     free(string);
  629. X     Leave(-1)
  630. X}
  631. X
  632. X/*
  633. X * Look up a string in the key expression table and return its mask, else
  634. X * return -1.
  635. X */
  636. Xint keyexprlookup(string)
  637. Xchar *string;
  638. X{
  639. X     int i;
  640. X     
  641. X     Entry("keyexprlookup")
  642. X
  643. X     for (i = 0; KeyExprTbl[i].name; i++) {
  644. X      if (!strcmp(KeyExprTbl[i].name, string)) {
  645. X           free(string);
  646. X           Leave(KeyExprTbl[i].mask)
  647. X      }
  648. X     }
  649. X     sprintf(msg,"key expression error: \"%s\"", string);
  650. X     yyerror(msg);
  651. X     free(string);
  652. X     Leave(-1)
  653. X}
  654. X
  655. Xint gravitylookup(string)
  656. Xchar *string;
  657. X{
  658. X     int i;
  659. X
  660. X     Entry("gravitylookup")
  661. X
  662. X     for (i = 0; GravityExprTbl[i].name; i++) {
  663. X      if (!strcmp(GravityExprTbl[i].name, string)) {
  664. X           free(string);
  665. X           Leave(GravityExprTbl[i].mask)
  666. X      }
  667. X     }
  668. X     sprintf(msg, "gravity expression error: \"%s\"", string);
  669. X     yyerror(msg);
  670. X     free(string);
  671. X     Leave(-1);
  672. X}
  673. X    
  674. X/*
  675. X * Look up a string in the context expression table and return its mask, else
  676. X * return -1.
  677. X */
  678. Xcontexprlookup(string)
  679. Xchar *string;
  680. X{
  681. X     int i;
  682. X     
  683. X     Entry("contexprlookup")
  684. X
  685. X     for (i = 0; ContExprTbl[i].name; i++) {
  686. X      if (!strcmp(ContExprTbl[i].name, string)) {
  687. X           free(string);
  688. X           Leave(ContExprTbl[i].mask)
  689. X      }
  690. X     }
  691. X     sprintf(msg,"context expression error: \"%s\"", string);
  692. X     yyerror(msg);
  693. X     free(string);
  694. X     Leave(-1)
  695. X}
  696. X
  697. X/*
  698. X * Look up a string in the button expression table and return its mask, else
  699. X * return -1.
  700. X */
  701. Xbuttexprlookup(string)
  702. Xchar *string;
  703. X{
  704. X     int i;
  705. X     
  706. X     Entry("buttexprlookup")
  707. X
  708. X     for (i = 0; ButtModTbl[i].name; i++) {
  709. X      if (!strcmp(ButtModTbl[i].name, string)) {
  710. X           free(string);
  711. X           Leave(ButtModTbl[i].mask)
  712. X      }
  713. X     }
  714. X     sprintf(msg,"button modifier error: \"%s\"", string);
  715. X     yyerror(msg);
  716. X     free(string);
  717. X     Leave(-1)
  718. X}
  719. X
  720. X/*
  721. X * Scan a string and return an integer.  Report an error if any
  722. X * non-numeric characters are found.
  723. X */
  724. Xy_atoi(s)
  725. Xchar *s;
  726. X{
  727. X     int n = 0;
  728. X     
  729. X     Entry("y_atoi")
  730. X
  731. X     while (*s) {
  732. X      if (*s >= '0' && *s <= '9')
  733. X           n = 10 * n + *s - '0';
  734. X      else {
  735. X           yyerror("non-numeric argument");
  736. X           Leave(-1)
  737. X      }
  738. X      s++;
  739. X     }
  740. X     Leave(n)
  741. X}
  742. X
  743. X/*
  744. X * Append s2 to s1, extending s1 as necessary.
  745. X */
  746. Xchar *
  747. X     strconcat(s1, s2)
  748. Xchar *s1, *s2;
  749. X{
  750. X     char *malloc();
  751. X     char *p;
  752. X     
  753. X     Entry("strconcat")
  754. X
  755. X     p = malloc(strlen(s1) + strlen(s2) + 2);
  756. X     sprintf(p, "%s %s", s1, s2);
  757. X     free(s1);
  758. X     free(s2);
  759. X     s1 = p;
  760. X     Leave(s1)
  761. X}
  762. X
  763. X/*
  764. X * Check a button expression for errors.
  765. X */
  766. Xint CheckButtonState(expr)
  767. Xint expr;
  768. X{
  769. X     Entry("CheckButtonState")
  770. X
  771. X     /*
  772. X      * Check for one (and only one) button.
  773. X      */
  774. X     switch (expr & (LeftMask | MiddleMask | RightMask)) {
  775. X     case 0:
  776. X      yyerror("no button specified");
  777. X      break;
  778. X     case LeftMask:
  779. X      break;
  780. X     case MiddleMask:
  781. X      break;
  782. X     case RightMask:
  783. X      break;
  784. X     default:
  785. X      yyerror("more than one button specified");
  786. X     }
  787. X     
  788. X     /*
  789. X      * Check for one (and only one) up/down/motion modifier.
  790. X      */
  791. X     switch (expr & (ButtonUp | ButtonDown | DeltaMotion)) {
  792. X     case 0:
  793. X      yyerror("no button action specified");
  794. X      break;
  795. X     case ButtonUp:
  796. X      break;
  797. X     case ButtonDown:
  798. X      break;
  799. X     case DeltaMotion:
  800. X      break;
  801. X     default:
  802. X      yyerror("only one of up/down/motion may be specified");
  803. X     }
  804. X     Leave(expr)
  805. X}
  806. X
  807. X/*
  808. X * Bind button/key/context to a function.
  809. X */
  810. Xbindtofunc(index, mask, context, name)
  811. Xint index;        /* Index into keyword table. */
  812. Xint mask;        /* Button/key/modifier mask. */
  813. Xint context;        /* ROOT, WINDOW, TITLE, ICON, GADGET or BORDER */
  814. Xchar *name;        /* Menu, if needed. */
  815. X{
  816. X     Entry("bindtofunc")
  817. X
  818. X     setbinding(context, index, mask, name);
  819. X     Leave_void
  820. X}
  821. X
  822. X/*
  823. X * Allocate a Binding type and return a pointer.
  824. X */
  825. XBinding *
  826. X     AllocBinding()
  827. X{
  828. X     Binding *ptr;
  829. X     
  830. X     Entry("AllocBinding")
  831. X
  832. X     if (!(ptr = (Binding *)calloc(1, sizeof(Binding)))) {
  833. X      sprintf(msg, "Can't allocate binding--out of space\n");
  834. X      yyerror(msg);
  835. X      exit(1);
  836. X     }
  837. X     Leave(ptr)
  838. X}
  839. X
  840. X/*
  841. X * Stash the data in a Binding.
  842. X */
  843. Xsetbinding(cont, i, m, mname)
  844. Xint cont;        /* Context: ROOT, WINDOW, or ICON. */
  845. Xint i;            /* Keyword table index. */
  846. Xint m;        /* Key/button/modifier mask. */
  847. Xchar *mname;        /* Pointer to menu name, if needed. */
  848. X{
  849. X     Binding *ptr;
  850. X     MenuInfo *mi;
  851. X
  852. X     Entry("setbinding")
  853. X
  854. X     ptr = AllocBinding();
  855. X     ptr->context = cont;
  856. X     ptr->mask = m;
  857. X     ptr->func = KeywordTable[i].fptr;
  858. X     ptr->menuname = mname;
  859. X     switch (m & (LeftMask | MiddleMask | RightMask)) {
  860. X     case LeftMask:
  861. X      ptr->button = LeftButton;
  862. X      break;
  863. X     case MiddleMask:
  864. X      ptr->button = MiddleButton;
  865. X      break;
  866. X     case RightMask:
  867. X      ptr->button = RightButton;
  868. X      break;
  869. X     }
  870. X     appendbinding(ptr);
  871. X     Leave_void
  872. X}
  873. X
  874. X/*
  875. X * Append a Binding to the Bindings list.
  876. X */
  877. Xappendbinding(binding)
  878. XBinding *binding;
  879. X{
  880. X     Binding *ptr;
  881. X     
  882. X     Entry("appendbinding")
  883. X
  884. X     if (Blist == NULL)
  885. X      Blist = binding;
  886. X     else {
  887. X      for(ptr = Blist; ptr->next; ptr = ptr->next) /* NULL */;
  888. X      ptr->next = binding;
  889. X      ptr = ptr->next;
  890. X      ptr->next = NULL;
  891. X     }
  892. X     Leave_void
  893. X}
  894. X
  895. X/*
  896. X * Allocate an action line and return a pointer.
  897. X */
  898. XActionLine *AllocActionLine()
  899. X{
  900. X     ActionLine *ptr;
  901. X     
  902. X     Entry("AllocActionLine")
  903. X
  904. X     if (!(ptr = (ActionLine *)calloc(1, sizeof(ActionLine)))) {
  905. X      sprintf(msg, "Can't allocate action line--out of space\n");
  906. X      yyerror(msg);
  907. X     }
  908. X     Leave(ptr)
  909. X}
  910. X
  911. X/*
  912. X * Allocate a MenuInfo structure and return a pointer.
  913. X */
  914. XMenuInfo *AllocMenuInfo()
  915. X{
  916. X     MenuInfo *ptr;
  917. X     
  918. X     Entry("AllocMenuInfo")
  919. X
  920. X     if (!(ptr = (MenuInfo *)calloc(1, sizeof(MenuInfo)))) {
  921. X      sprintf(msg, "Can't allocate menu storage--out of space\n");
  922. X      yyerror(msg);
  923. X     }
  924. X     Leave(ptr)
  925. X}
  926. X
  927. X/*
  928. X * Allocate a MenuLink structure and return a pointer.
  929. X */
  930. XMenuLink *AllocMenuLink()
  931. X{
  932. X     MenuLink *ptr;
  933. X     Entry("AllocMenuLink")
  934. X
  935. X     if (!(ptr = (MenuLink *)calloc(1, sizeof(MenuLink)))) {
  936. X      sprintf(msg, "Can't allocate menu linked list storage--out of space\n");
  937. X      yyerror(msg);
  938. X     }
  939. X     Leave(ptr)
  940. X}
  941. X
  942. X/*
  943. X * Return storage for Gadgets[] array.
  944. X */
  945. XGadgetDecl **allocate_gadgets()
  946. X{
  947. X     GadgetDecl **tmp;
  948. X     int i;
  949. X
  950. X     Entry("allocate_gadgets")
  951. X
  952. X     tmp = (GadgetDecl **)malloc(MAX_GADGETS * sizeof(GadgetDecl *));
  953. X     if (!tmp) {
  954. X      sprintf(msg, "Can't allocate storage for Gadgets -- out of space\n");
  955. X      yyerror(msg);
  956. X      Leave(NULL)
  957. X     }
  958. X     for (i = 0; i < MAX_GADGETS; i++)
  959. X      tmp[i] = (GadgetDecl *)0;
  960. X     Leave(tmp)
  961. X}
  962. X
  963. X/*
  964. X * Stash a gadget record
  965. X */
  966. XGadgetDecl *stashGadget(n, s, type)
  967. Xint n;
  968. Xchar *s;
  969. Xint type;
  970. X{
  971. X     GadgetDecl *tmp;
  972. X
  973. X     Entry("stashGadget")
  974. X
  975. X     if (!Gadgets)
  976. X      Gadgets = (GadgetDecl **)allocate_gadgets();
  977. X     if (n < 0 || n >= NumGadgets) {
  978. X      sprintf(msg, "stashGadget on gadget #%d when maxgadget = %d\n",
  979. X          n, NumGadgets);
  980. X      yyerror(msg);
  981. X      Leave(NULL)
  982. X     }
  983. X     if (Gadgets[n]) {
  984. X      sprintf(msg, "gadget #%d redefined\n", n);
  985. X      yywarn(msg);
  986. X      FreeGadget(n);
  987. X          tmp = Gadgets[n];
  988. X     }
  989. X     else
  990. X      Gadgets[n] = tmp = (GadgetDecl *)malloc(sizeof(GadgetDecl));
  991. X     if (!Gadgets[n]) {
  992. X      sprintf(msg, "Can't allocate new gadget, out of space!\n");
  993. X      yyerror(msg);
  994. X      Leave(NULL)
  995. X     }
  996. X     tmp->data = (unsigned char *)NULL;
  997. X     tmp->name = (unsigned char *)NULL;
  998. X     tmp->high = tmp->wide = 0;
  999. X     tmp->gravity = g_gravity;
  1000. X     tmp->offset = g_offset;
  1001. X     tmp->forecolor = g_forecolor;
  1002. X     tmp->backcolor = g_backcolor;
  1003. X     tmp->fontInfo = g_font;
  1004. X     if (type != C_STRING && type != C_PIXMAP) {
  1005. X      sprintf(msg, "Invalid gadget specification for gadget #%d\n", n);
  1006. X      yyerror(msg);
  1007. X      NumGadgets = 0;
  1008. X          Leave(NULL)
  1009. X     }
  1010. X     if (type == C_PIXMAP) {
  1011. X      int junk;
  1012. X      char *nm = s;
  1013. X
  1014. X      s = expand_from_path(s);
  1015. X      if (!s) {
  1016. X           sprintf(msg, "Can't find pixmap file '%s' for gadget #%d\n",
  1017. X               nm, n);
  1018. X           yywarn(msg);
  1019. X           tmp->data = (unsigned char *)gray_bits;
  1020. X           tmp->high = gray_height;
  1021. X           tmp->wide = gray_width;
  1022. X      }
  1023. X      else if (XReadBitmapFileData(s, &(tmp->wide),
  1024. X                  &(tmp->high), &(tmp->data), &junk, &junk)
  1025. X          != BitmapSuccess) {
  1026. X           sprintf(msg, "Can't open pixmap file '%s' for gadget #%d.\n", s, n);
  1027. X           yyerror(msg);
  1028. X           tmp->data = (unsigned char *)gray_bits;
  1029. X           tmp->high = gray_height;
  1030. X           tmp->wide = gray_width;
  1031. X      }
  1032. X      free(s);
  1033. X      if (tmp->high > gadgetHeight)
  1034. X           gadgetHeight = tmp->high;
  1035. X     }
  1036. X     else if (type == C_STRING) { /* it's a label */
  1037. X      tmp->name = expand_metachars(s);
  1038. X      if (!tmp->fontInfo) {
  1039. X           if (!GFontInfo) {
  1040. X            GFontInfo = GetFontRes("gadget.font", DEF_GADGET_FONT);
  1041. X            if (!GFontInfo) {
  1042. X             sprintf(msg, "Can't get a default gadget font.\n");
  1043. X             yyerror(msg);
  1044. X             Leave(NULL)
  1045. X            }
  1046. X           }
  1047. X           tmp->fontInfo = GFontInfo;
  1048. X      }
  1049. X      if (strlen(tmp->name) > 1) {
  1050. X           tmp->wide = XTextWidth(tmp->fontInfo, tmp->name, strlen(tmp->name));
  1051. X           tmp->high = tmp->fontInfo->max_bounds.ascent +
  1052. X            tmp->fontInfo->max_bounds.descent + 2;
  1053. X      }
  1054. X      else {
  1055. X           XCharStruct chinfo;
  1056. X           int asc, desc, dir;
  1057. X
  1058. X           XTextExtents(tmp->fontInfo, tmp->name, 1, &dir, &asc,
  1059. X                &desc, &chinfo);
  1060. X           tmp->wide = chinfo.width;
  1061. X           tmp->high = chinfo.ascent + chinfo.descent;
  1062. X      }
  1063. X      tmp->wide += 2 * GadgetBorder;
  1064. X          if (tmp->high > gadgetHeight)
  1065. X           gadgetHeight = tmp->high;
  1066. X     }
  1067. X     Leave(tmp)
  1068. X}
  1069. X
  1070. X/*
  1071. X * This routine expands '\' notation in a string, ala C. Mostly useful for
  1072. X * imbedding weird characters in strings that turn into interesting symbols
  1073. X * from some font. Unlike C, however, numeric constants (\nnn) are in
  1074. X * decimal, not octal. This was done because the most popular glyphs
  1075. X * (in cursorfont.h) are identified in decimal. There are some other cute
  1076. X * "metacharacters" that expand to the window name, icon name, etc.
  1077. X */
  1078. Xunsigned char *expand_metachars(s)
  1079. Xregister unsigned char *s;
  1080. X{
  1081. X     register int i, len, val, n;
  1082. X     unsigned char *cp, num[5];
  1083. X
  1084. X     Entry("expand_metachars")
  1085. X
  1086. X     if (!s)
  1087. X      Leave(s)
  1088. X     len = strlen(s);
  1089. X     for (i = 0; i < len; i++)
  1090. X      if (s[i] == '\\')
  1091. X           break;
  1092. X     if (i == len)
  1093. X      Leave(s)
  1094. X     /* we know the string is going to get shorter, len is correct */
  1095. X     cp = (unsigned char *)malloc(len);
  1096. X     i = n = 0;
  1097. X     while (*s) {
  1098. X      if (*s == '\\') {
  1099. X           s++;
  1100. X           while (*s && *s >= '0' && *s <= '9') {
  1101. X            num[n++] = *s;
  1102. X            s++;
  1103. X           }
  1104. X           if (n) {
  1105. X            if (n > 4)
  1106. X             n = 4;
  1107. X            num[n] = '\0';
  1108. X            cp[i++] = (char)atoi(num);
  1109. X            n = 0;
  1110. X           }
  1111. X           else if (*s) {
  1112. X            switch(*s) {
  1113. X
  1114. X            case 'b':
  1115. X             val = 8;
  1116. X             break;
  1117. X
  1118. X            case 'f':
  1119. X             val = 12;
  1120. X
  1121. X            case 'n':
  1122. X             val = 10;
  1123. X             break;
  1124. X
  1125. X            case 'r':
  1126. X             val = 13;
  1127. X             break;
  1128. X
  1129. X            case 't':
  1130. X             val = 9;
  1131. X             break;
  1132. X
  1133. X            default:
  1134. X             val = *s;
  1135. X             break;
  1136. X            }
  1137. X            cp[i++] = val;
  1138. X            s++;
  1139. X           }
  1140. X      }
  1141. X      else {
  1142. X           cp[i++] = *s;
  1143. X           s++;
  1144. X      }
  1145. X     }
  1146. X     cp[i] = '\0';
  1147. X     Leave(cp)
  1148. X}
  1149. X      
  1150. X/*
  1151. X * Stash the data in an action line.
  1152. X */
  1153. XActionLine *StashActionLine(type, string)
  1154. Xint type;
  1155. Xchar *string;
  1156. X{
  1157. X     ActionLine *ptr;
  1158. X     
  1159. X     Entry("StashActionLine")
  1160. X
  1161. X     ptr = AllocActionLine();
  1162. X     ptr->type = type;
  1163. X     ptr->text = string;
  1164. X     Leave(ptr)
  1165. X}
  1166. X
  1167. X/*
  1168. X * Stash menu data in a MenuInfo structure;
  1169. X */
  1170. XMenuInfo *stashmenuinfo(name, line, pixmap)
  1171. Xchar *name;
  1172. XActionLine *line;
  1173. Xchar *pixmap;
  1174. X{
  1175. X     MenuInfo *ptr;
  1176. X     
  1177. X     Entry("stashmenuinfo")
  1178. X
  1179. X     ptr = AllocMenuInfo();
  1180. X     ptr->name = name;
  1181. X     ptr->line = line;
  1182. X     ptr->pixmapname = pixmap;
  1183. X     ptr->menu = 0;
  1184. X     Leave(ptr)
  1185. X}
  1186. X
  1187. X/*
  1188. X * Stash menu info data in a MenuLink structure;
  1189. X */
  1190. XMenuLink *stashmenulink(menuinfo)
  1191. XMenuInfo *menuinfo;
  1192. X{
  1193. X     MenuLink *ptr;
  1194. X     
  1195. X     Entry("stashmenulink")
  1196. X
  1197. X     ptr = AllocMenuLink();
  1198. X     ptr->next = NULL;
  1199. X     ptr->menu = menuinfo;
  1200. X     Leave(ptr)
  1201. X}
  1202. X
  1203. X/*
  1204. X * Append an action line to a linked list of menu lines.
  1205. X */
  1206. XActionLine *appendmenuline(list, line)
  1207. XActionLine *list;
  1208. XActionLine *line;
  1209. X{
  1210. X     ActionLine *ptr;
  1211. X     
  1212. X     Entry("appendmenuline")
  1213. X
  1214. X     if (list == NULL)
  1215. X      list = line;
  1216. X     else {
  1217. X      for(ptr = list; ptr->next; ptr = ptr->next) /* NULL */;
  1218. X      ptr->next = line;
  1219. X      ptr = ptr->next;
  1220. X      ptr->next = NULL;
  1221. X     }
  1222. X     Leave(list)
  1223. X}
  1224. X
  1225. X/*
  1226. X * Append a menu to a linked list of menus.
  1227. X */
  1228. XMenuLink *
  1229. X     appendmenulink(list, link)
  1230. XMenuLink *list;
  1231. XMenuLink *link;
  1232. X{
  1233. X     MenuLink *ptr;
  1234. X     
  1235. X     Entry("appendmenulink")
  1236. X
  1237. X     if (list == NULL)
  1238. X      list = link;
  1239. X     else {
  1240. X      for(ptr = list; ptr->next; ptr = ptr->next) /* NULL */;
  1241. X      ptr->next = link;
  1242. X      ptr = ptr->next;
  1243. X      ptr->next = NULL;
  1244. X     }
  1245. X     Leave(list)
  1246. X}
  1247. X     
  1248. X/*
  1249. X * Reset all previous bindings and free the space allocated to them.
  1250. X */
  1251. XBoolean ResetBindings()
  1252. X{
  1253. X     Binding *ptr, *nextptr;
  1254. X     
  1255. X     Entry("ResetBindings")
  1256. X
  1257. X     for(ptr = Blist; ptr; ptr = nextptr) {
  1258. X      nextptr = ptr->next;
  1259. X      free(ptr);
  1260. X     }
  1261. X     Blist = NULL;
  1262. X     Leave_void
  1263. X}
  1264. X
  1265. X/*
  1266. X * De-allocate all menus.
  1267. X */
  1268. XBoolean ResetMenus()
  1269. X{
  1270. X     MenuLink *mptr, *next_mptr;
  1271. X     register ActionLine *lptr, *next_lptr;
  1272. X     Entry("ResetMenus")
  1273. X     if (!Menus)
  1274. X    Leave_void
  1275. X     for(mptr = Menus; mptr; mptr = next_mptr) {
  1276. X      free(mptr->menu->name);
  1277. X      RTLMenu_Destroy(mptr->menu->menu);
  1278. X      for(lptr = mptr->menu->line; lptr; lptr = next_lptr) {
  1279. X           free(lptr->name);
  1280. X           if (lptr->text) free(lptr->text);
  1281. X           next_lptr = lptr->next;
  1282. X           free(lptr);
  1283. X      }
  1284. X      next_mptr = mptr->next;
  1285. X      free(mptr);
  1286. X     }
  1287. X     Menus = NULL;
  1288. X     Leave_void
  1289. X}
  1290. END_OF_awm/gram.y
  1291. if test 26836 -ne `wc -c <awm/gram.y`; then
  1292.     echo shar: \"awm/gram.y\" unpacked with wrong size!
  1293. fi
  1294. # end of overwriting check
  1295. fi
  1296. echo shar: End of archive 10 \(of 13\).
  1297. cp /dev/null ark10isdone
  1298. MISSING=""
  1299. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1300.     if test ! -f ark${I}isdone ; then
  1301.     MISSING="${MISSING} ${I}"
  1302.     fi
  1303. done
  1304. if test "${MISSING}" = "" ; then
  1305.     echo You have unpacked all 13 archives.
  1306.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1307. else
  1308.     echo You still need to unpack the following archives:
  1309.     echo "        " ${MISSING}
  1310. fi
  1311. ##  End of shell archive.
  1312. exit 0
  1313. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  1314.